import { EventSubscription, Platform } from 'react-native';
import { DlnaPlayerInterface } from './interface';
import { DlnaPlayerEventType, eventEmitter } from './events';
import { DlnaPlayerModule, validateUrl, validateDeviceId, validateVolume, validatePosition, withTimeout, deviceCache } from './utils';
import { Device, PlaybackStatus, PermissionCheckResult, PermissionRequestOptions, PermissionInfoResult, PermanentlyDeniedPermissions } from './types';
import { DlnaError, DlnaErrorCode } from './errors';
import {
  PermissionType,
  PermissionStatus,
  PermissionStatusEventData,
  checkPermissions as checkPermissionsFromModule,
  requestPermissions as requestPermissionsFromModule,
  checkSinglePermission as checkSinglePermissionFromModule,
  addPermissionStatusChangeListener,
  removePermissionStatusChangeListener,
  getRequiredPermissions as getRequiredPermissionsFromModule,
  checkPermanentlyDeniedPermissionsStatus,
  resetPermissionRequestHistory as resetPermissionRequestHistoryFromModule
} from './permissions';

// 检测是否在 Expo 环境中
let isExpo = false;
try {
  // 使用动态导入以避免在非 Expo 环境中出错
  // @ts-ignore
  const Constants = require('expo-constants').default;
  isExpo = !!Constants;
} catch (error) {
  // 不是 Expo 环境，忽略错误
}

/**
 * DLNA播放器实现
 */
export const DlnaPlayerImplementation: DlnaPlayerInterface = {
  searchDevices: async (): Promise<Device[]> => {
    try {
      // 首先检查权限
      const permissionCheckResult = await checkPermissionsFromModule();
      if (!permissionCheckResult.hasPermissions) {
        throw DlnaError.permissionError(
          permissionCheckResult.missingPermissions || [],
          '搜索设备需要网络和本地网络权限'
        );
      }
      
      let devices: Device[] = [];

      // Expo环境中可能需要特殊处理
      if (isExpo && Platform.OS === 'ios') {
        console.warn(
          'React Native DLNA Player: 在Expo iOS环境中，搜索设备功能可能受限。请确保已在app.json中配置了必要的权限。'
        );
      }
      
      if (DlnaPlayerModule.searchDevices) {
        // 使用超时保护，防止操作无响应
        devices = await withTimeout(
          DlnaPlayerModule.searchDevices(),
          10000,
          '搜索设备超时'
        );
      } else if (DlnaPlayerModule.startScan) {
        await DlnaPlayerModule.startScan();
        if (DlnaPlayerModule.getDeviceList) {
          devices = await withTimeout(
            DlnaPlayerModule.getDeviceList(),
            10000,
            '获取设备列表超时'
          );
        }
      } else {
        throw DlnaError.methodNotImplemented('searchDevices');
      }
      
      // 更新设备缓存
      devices.forEach(device => {
        deviceCache.addDevice(device);
      });
      
      return devices;
    } catch (error) {
      if (error instanceof DlnaError) {
        throw error;
      }
      throw DlnaError.networkError((error as Error).message || '网络连接错误');
    }
  },
  
  searchDevicesIncremental: async (options = {}): Promise<Device[]> => {
    try {
      const { timeout = 10000, useCached = true, clearCache = false } = options;
      
      // 检查权限
      const permissionCheckResult = await checkPermissionsFromModule();
      if (!permissionCheckResult.hasPermissions) {
        throw DlnaError.permissionError(
          permissionCheckResult.missingPermissions || [],
          '搜索设备需要网络和本地网络权限'
        );
      }
      
      // 如果需要清除缓存
      if (clearCache) {
        deviceCache.clear();
      } else {
        // 清除过期设备
        deviceCache.clearExpired();
      }
      
      // 获取缓存的设备
      const cachedDevices = useCached ? deviceCache.getAllDevices() : [];
      
      // 异步启动设备搜索
      if (DlnaPlayerModule.searchDevicesEnhanced) {
        // 使用增强的搜索API，在指定时间内搜索并通过事件通知
        setTimeout(() => {
          DlnaPlayerModule.searchDevicesEnhanced(timeout, clearCache ? true : false)
            .catch((error: any) => {
              console.error('增量搜索设备出错:', error);
            });
        }, 0);
      } else if (DlnaPlayerModule.startScan) {
        // 使用基本的搜索API
        setTimeout(() => {
          DlnaPlayerModule.startScan()
            .catch((error: any) => {
              console.error('开始扫描设备出错:', error);
            });
        }, 0);
      } else {
        throw DlnaError.methodNotImplemented('searchDevicesIncremental');
      }
      
      return cachedDevices;
    } catch (error) {
      throw DlnaError.fromNativeError(error);
    }
  },
  
  stopDeviceSearch: async (): Promise<boolean> => {
    try {
      if (DlnaPlayerModule.stopDeviceSearch) {
        return await DlnaPlayerModule.stopDeviceSearch();
      } else if (DlnaPlayerModule.stopScan) {
        await DlnaPlayerModule.stopScan();
        return true;
      }
      
      throw DlnaError.methodNotImplemented('stopDeviceSearch');
    } catch (error: any) {
      throw DlnaError.fromNativeError(error);
    }
  },
  
  addDeviceFoundListener: (listener: (device: Device) => void): EventSubscription => {
    return eventEmitter.addListener(DlnaPlayerEventType.DEVICE_FOUND, (device: Device) => {
      // 将设备添加到缓存
      deviceCache.addDevice(device);
      // 调用监听器
      listener(device);
    });
  },
  
  addDeviceLostListener: (listener: (device: Device) => void): EventSubscription => {
    return eventEmitter.addListener(DlnaPlayerEventType.DEVICE_LOST, listener);
  },
  
  connectToDevice: async (deviceId: string): Promise<boolean> => {
    try {
      const validatedDeviceId = validateDeviceId(deviceId);
      
      // 首先检查设备缓存
      const cachedDevice = deviceCache.getDevice(validatedDeviceId);
      if (!cachedDevice) {
        console.warn(`设备 ${validatedDeviceId} 未在缓存中找到，尝试直接连接`);
      }
      
      // 使用超时保护，防止连接操作无响应
      const result = await withTimeout(
        DlnaPlayerModule.connectToDevice(validatedDeviceId),
        15000,
        `连接设备 ${validatedDeviceId} 超时`
      );
      
      if (!result) {
        throw DlnaError.connectionFailed(deviceId);
      }
      
      return Boolean(result);
    } catch (error) {
      if (error instanceof DlnaError) {
        throw error;
      }
      throw DlnaError.connectionFailed(deviceId, error);
    }
  },
  
  disconnectFromDevice: async (): Promise<boolean> => {
    try {
      const result = await withTimeout(
        DlnaPlayerModule.disconnectFromDevice(),
        10000,
        '断开设备连接超时'
      );
      
      if (!result) {
        throw new DlnaError(
          DlnaErrorCode.DISCONNECTION_FAILED,
          '断开设备连接失败'
        );
      }
      return Boolean(result);
    } catch (error: any) {
      throw DlnaError.fromNativeError(error);
    }
  },
  
  playVideo: async (url: string, title?: string, subtitle?: string, coverUrl?: string): Promise<boolean> => {
    try {
      const validatedUrl = validateUrl(url);
      
      if (DlnaPlayerModule.playVideo) {
        const result = await withTimeout(
          DlnaPlayerModule.playVideo(validatedUrl, title, subtitle, coverUrl),
          15000,
          '播放视频操作超时'
        );
        
        if (!result) {
          throw DlnaError.playbackFailed(url);
        }
        return Boolean(result);
      } else if (DlnaPlayerModule.startPlay) {
        // 向后兼容旧的API
        try {
          await withTimeout(
            DlnaPlayerModule.startPlay({
              url: validatedUrl,
              title: title || '',
              subtitle: subtitle,
              coverUrl: coverUrl
            }),
            15000,
            '播放视频操作超时'
          );
          return true;
        } catch (error: any) {
          throw DlnaError.playbackFailed(url, error);
        }
      }
      
      throw DlnaError.methodNotImplemented('playVideo');
    } catch (error: any) {
      if (error instanceof DlnaError) {
        throw error;
      }
      throw DlnaError.playbackFailed(url, error);
    }
  },
  
  pauseVideo: async (): Promise<boolean> => {
    try {
      if (DlnaPlayerModule.pauseVideo) {
        const result = await DlnaPlayerModule.pauseVideo();
        if (!result) {
          throw new DlnaError(DlnaErrorCode.PAUSE_FAILED, '暂停视频失败');
        }
        return result;
      } else if (DlnaPlayerModule.pause) {
        await DlnaPlayerModule.pause();
        return true;
      }
      
      throw DlnaError.methodNotImplemented('pauseVideo');
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.PAUSE_FAILED,
        '暂停视频失败',
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  resumeVideo: async (): Promise<boolean> => {
    try {
      if (DlnaPlayerModule.resumeVideo) {
        const result = await DlnaPlayerModule.resumeVideo();
        if (!result) {
          throw new DlnaError(DlnaErrorCode.RESUME_FAILED, '恢复播放失败');
        }
        return result;
      } else if (DlnaPlayerModule.resume) {
        await DlnaPlayerModule.resume();
        return true;
      }
      
      throw DlnaError.methodNotImplemented('resumeVideo');
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.RESUME_FAILED,
        '恢复播放失败',
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  stopVideo: async (): Promise<boolean> => {
    try {
      if (DlnaPlayerModule.stopVideo) {
        const result = await DlnaPlayerModule.stopVideo();
        if (!result) {
          throw new DlnaError(DlnaErrorCode.STOP_FAILED, '停止播放失败');
        }
        return result;
      } else if (DlnaPlayerModule.stop) {
        await DlnaPlayerModule.stop();
        return true;
      }
      
      throw DlnaError.methodNotImplemented('stopVideo');
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.STOP_FAILED,
        '停止播放失败',
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  seekTo: async (position: number): Promise<boolean> => {
    try {
      const validatedPosition = validatePosition(position);
      
      if (DlnaPlayerModule.seekTo) {
        const result = await DlnaPlayerModule.seekTo(validatedPosition);
        if (!result) {
          throw new DlnaError(
            DlnaErrorCode.SEEK_FAILED,
            `跳转到 ${position} 秒失败`
          );
        }
        return result;
      } else if (DlnaPlayerModule.seekToPosition) {
        // 向后兼容旧的API
        try {
          await DlnaPlayerModule.seekToPosition(validatedPosition);
          return true;
        } catch (error) {
          throw new DlnaError(
            DlnaErrorCode.SEEK_FAILED,
            `跳转到 ${position} 秒失败`,
            error
          );
        }
      }
      
      throw DlnaError.methodNotImplemented('seekTo');
    } catch (error) {
      if (error instanceof DlnaError) {
        throw error;
      }
      throw new DlnaError(
        DlnaErrorCode.SEEK_FAILED,
        `跳转到 ${position} 秒失败`,
        error
      );
    }
  },
  
  getPlaybackStatus: async (): Promise<PlaybackStatus> => {
    try {
      if (!DlnaPlayerModule.getPlaybackStatus) {
        throw DlnaError.methodNotImplemented('getPlaybackStatus');
      }
      
      return await DlnaPlayerModule.getPlaybackStatus();
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.GET_STATUS_FAILED,
        '获取播放状态失败',
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  setVolume: async (volume: number): Promise<boolean> => {
    try {
      const validatedVolume = validateVolume(volume);
      
      if (DlnaPlayerModule.setVolume) {
        const result = await DlnaPlayerModule.setVolume(validatedVolume);
        if (!result) {
          throw new DlnaError(
            DlnaErrorCode.VOLUME_CONTROL_FAILED,
            `设置音量到 ${volume} 失败`
          );
        }
        return result;
      } else if (DlnaPlayerModule.setDeviceVolume) {
        // 向后兼容旧的API
        try {
          await DlnaPlayerModule.setDeviceVolume(validatedVolume);
          return true;
        } catch (error) {
          throw new DlnaError(
            DlnaErrorCode.VOLUME_CONTROL_FAILED,
            `设置音量到 ${volume} 失败`,
            error
          );
        }
      }
      
      throw DlnaError.methodNotImplemented('setVolume');
    } catch (error) {
      if (error instanceof DlnaError) {
        throw error;
      }
      throw new DlnaError(
        DlnaErrorCode.VOLUME_CONTROL_FAILED,
        `设置音量到 ${volume} 失败`,
        error
      );
    }
  },
  
  getVolume: async (): Promise<number> => {
    try {
      if (!DlnaPlayerModule.getVolume) {
        throw DlnaError.methodNotImplemented('getVolume');
      }
      
      return await DlnaPlayerModule.getVolume();
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.VOLUME_CONTROL_FAILED,
        '获取音量失败',
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  setMute: async (mute: boolean): Promise<boolean> => {
    try {
      if (!DlnaPlayerModule.setMute) {
        throw DlnaError.methodNotImplemented('setMute');
      }
      
      const result = await DlnaPlayerModule.setMute(mute);
      if (!result) {
        throw new DlnaError(
          DlnaErrorCode.VOLUME_CONTROL_FAILED,
          `设置静音为 ${mute ? '开启' : '关闭'} 失败`
        );
      }
      return result;
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.VOLUME_CONTROL_FAILED,
        `设置静音为 ${mute ? '开启' : '关闭'} 失败`,
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  getMute: async (): Promise<boolean> => {
    try {
      if (!DlnaPlayerModule.getMute) {
        throw DlnaError.methodNotImplemented('getMute');
      }
      
      return await DlnaPlayerModule.getMute();
    } catch (error) {
      throw new DlnaError(
        DlnaErrorCode.VOLUME_CONTROL_FAILED,
        '获取静音状态失败',
        error instanceof Error ? { message: error.message } : error
      );
    }
  },
  
  /**
   * 添加事件监听器
   */
  addEventListener(
    eventType: DlnaPlayerEventType,
    listener: (event: any) => void
  ): EventSubscription {
    return eventEmitter.addListener(eventType, listener);
  },
  
  /**
   * 移除事件监听器
   */
  removeEventListener(
    subscription: EventSubscription
  ): void {
    subscription.remove();
  },

  /**
   * 检查是否拥有所需权限
   */
  async checkPermissions(): Promise<PermissionCheckResult> {
    return checkPermissionsFromModule();
  },

  /**
   * 请求所需的权限
   */
  async requestPermissions(options?: PermissionRequestOptions): Promise<boolean> {
    return requestPermissionsFromModule(options);
  },
  
  /**
   * 检查单个权限状态
   */
  async checkSinglePermission(permissionType: PermissionType): Promise<PermissionStatus> {
    try {
      return await checkSinglePermissionFromModule(permissionType);
    } catch (error) {
      console.error('检查单个权限失败:', error);
      throw new DlnaError(
        DlnaErrorCode.PERMISSION_ERROR,
        '检查权限失败',
        error
      );
    }
  },
  
  /**
   * 添加权限状态变更监听器
   */
  addPermissionStatusChangeListener(
    listener: (event: PermissionStatusEventData) => void
  ): EventSubscription {
    return addPermissionStatusChangeListener(listener);
  },
  
  /**
   * 移除权限状态变更监听器
   */
  removePermissionStatusChangeListener(
    subscription: EventSubscription
  ): void {
    removePermissionStatusChangeListener(subscription);
  },
  
  /**
   * 获取所需的权限信息列表
   */
  async getRequiredPermissions(): Promise<PermissionInfoResult[]> {
    const permissions = getRequiredPermissionsFromModule();
    
    // 将权限信息转换为更简单的对象数组
    return permissions.map(perm => ({
      type: perm.type,
      name: perm.name,
      description: perm.description,
      rationale: perm.rationale,
      isRequired: perm.isRequired
    }));
  },
  
  /**
   * 检查是否有永久拒绝的权限
   */
  async checkPermanentlyDeniedPermissions(): Promise<PermanentlyDeniedPermissions> {
    try {
      return await checkPermanentlyDeniedPermissionsStatus();
    } catch (error) {
      console.error('检查永久拒绝权限失败:', error);
      throw new DlnaError(
        DlnaErrorCode.PERMISSION_ERROR,
        '检查永久拒绝权限失败',
        error
      );
    }
  },
  
  /**
   * 重置权限请求历史记录
   */
  resetPermissionRequestHistory(): void {
    resetPermissionRequestHistoryFromModule();
  },
  
  /**
   * 添加事件监听器（简化版API，为了向后兼容）
   */
  addListener(
    eventName: string,
    listener: (event: any) => void
  ): EventSubscription {
    return eventEmitter.addListener(eventName, listener);
  },
  
  /**
   * 开始搜索设备
   * @returns 操作是否成功
   */
  startScan: async (): Promise<boolean> => {
    try {
      // 首先检查权限
      const permissionCheckResult = await checkPermissionsFromModule();
      if (!permissionCheckResult.hasPermissions) {
        throw DlnaError.permissionError(
          permissionCheckResult.missingPermissions || [],
          '搜索设备需要网络和本地网络权限'
        );
      }
      
      if (DlnaPlayerModule.startScan) {
        return await DlnaPlayerModule.startScan();
      } else {
        throw DlnaError.methodNotImplemented('startScan');
      }
    } catch (error) {
      throw DlnaError.fromNativeError(error);
    }
  },
  
  /**
   * 停止搜索设备
   * @returns 操作是否成功
   */
  stopScan: async (): Promise<boolean> => {
    try {
      if (DlnaPlayerModule.stopScan) {
        return await DlnaPlayerModule.stopScan();
      } else {
        throw DlnaError.methodNotImplemented('stopScan');
      }
    } catch (error) {
      throw DlnaError.fromNativeError(error);
    }
  }
}; 